﻿/* *****************************************************************************
 * @ Encoding: UTF-8
 * @ File Name: naughty_differential_node_add.cpp
 * @ Author: carl
 * @ Email: naughtygeng@qq.com
 * @ Created Time: 2022-7月-07(星期四) 21:58:23
 * @ All Rights Reserved
 * *****************************************************************************/

#include "naughty_differential_node_add.hpp"
#include <cstdio>

namespace naughty_differential
{

node_add::node_add(std::shared_ptr<node_base> param01, std::shared_ptr<node_base> param02)
    :
        node_base({param01, param02})
{

}

node_add::node_add(std::vector<std::shared_ptr<node_base>> params)
    :
        node_base(params)
{

}

std::shared_ptr<node_base> node_add::differential(std::string variable)
{
	std::vector<std::shared_ptr<node_base>> parameters_diff_vector{get_parameters()[0]->differential(variable), get_parameters()[1]->differential(variable)};

    return std::make_shared<node_add>(parameters_diff_vector[0], parameters_diff_vector[1]);
}

enum node_type node_add::get_node_type()
{
    return node_type_add;
}

std::string node_add::serialize()
{
    return {};
}

std::string node_add::to_string() const
{
	return std::string("(") + get_parameters()[0]->to_string() + ") + (" + get_parameters()[1]->to_string() + ")";
}

std::shared_ptr<node_base> node_add::clone()
{
    return std::make_shared<node_add>(parameters_clone());
}

double node_add::get_value(std::map<std::string, double> val_value_map)
{
    std::vector<double> params_value = get_params_value(val_value_map);

    return params_value[0] + params_value[1];
}

std::string node_add::identity_string() const
{
	return std::string("add(") + get_parameters()[0]->to_string() + ", " + get_parameters()[1]->to_string() + ")";
}

std::vector<std::shared_ptr<node_base>> node_add::get_continual_add_parameters()
{
	std::vector<std::shared_ptr<node_base>> result;
	for (std::shared_ptr<node_base> &param : get_parameters())
	{
		if (param->get_node_type() == node_type_add)
		{
			std::shared_ptr<node_add> param_add = std::dynamic_pointer_cast<node_add>(param);
			assert(param_add);
			std::vector<std::shared_ptr<node_base>> results = param_add->get_continual_add_parameters();
			result.insert(result.end(), results.begin(), results.end());
		}
		else 
		{
			result.push_back(param);
		}
	}
	return result;
}

}
